package com.winse.java.converter.impl;

import java.io.IOException;
import java.io.InputStream;

import junit.framework.Assert;
import android.graphics.Color;
import android.graphics.Typeface;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;

import com.winse.java.javasource.JavaSource;
import com.winse.java.javasource.JavaSourceParser;
import com.winse.java.javasource.JavaSourceType;
import com.winse.java.options.JavaSourceConversionOptions;
import com.winse.java.options.style.JavaSourceStyleEntry;
import com.winse.java.options.style.RGB;

public class JavaSourceConverter {

	public static SpannableString convert(InputStream stream) throws IOException {
		Assert.assertNotNull("Trying to write out converted code without having InputStream set.", stream);

		JavaSourceConversionOptions options = JavaSourceConversionOptions.getDefault();
		JavaSource source = doParse(stream, options);

		/** FIXME Source code in JavaSource is readed from Reader */
		String sourceCode = source.getCode();
		SpannableString spannableSource = new SpannableString(sourceCode);

		JavaSourceType[] sourceTypes = source.getClassification();

		int start = 0;
		int end = start;
		while (start < sourceTypes.length) {
			while ((end < sourceTypes.length - 1)
					&& (sourceTypes[end + 1] == sourceTypes[start] || sourceTypes[end + 1] == JavaSourceType.BACKGROUND)) {
				++end;
			}

			JavaSourceStyleEntry style = /* JavaSourceStyleTable */options.getStyleTable().get(sourceTypes[start]);
			decorateSpannableStringWithStyle(spannableSource, start, end, style);

			start = end + 1;
			end = start;
		}

		return spannableSource;
	}

	private static JavaSource doParse(InputStream stream, JavaSourceConversionOptions options) {
		JavaSourceParser parser = new JavaSourceParser(options);
		JavaSource source = null;
		try {
			source = parser.parse(stream);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return source;
	}

	private static void decorateSpannableStringWithStyle(
			SpannableString spannableSource, 
			int start, 
			int end,
			JavaSourceStyleEntry style) 
	{
		RGB color = style.getColor();

		/** XXX setSpan like subString of String, start<=actual<end */
		spannableSource.setSpan(
				new ForegroundColorSpan(Color.rgb(color.getRed(), color.getGreen(), color.getBlue())),
				start, 
				end + 1, 
				Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		if (style.isBold()) {
			spannableSource.setSpan(new StyleSpan(Typeface.BOLD), start, end + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		}
		if (style.isItalic()) {
			spannableSource.setSpan(new StyleSpan(Typeface.ITALIC), start, end + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		}
	}

}
